
#ifndef SX_QVIEWPORT_H
#define SX_QVIEWPORT_H

#include <QWidget>

class QTimer;

/* Sx Library Includes */
#include <sxViewport.h>
#include <sxGraphicsContext.h>
#include <sxMouse.h>
#include <sxMath.h>

using Sx::Interface::MouseButton;
using Sx::Interface::ModifierKey;
using Sx::Interface::Viewport;
using Sx::Graphics::GraphicsContext;

namespace Sx {
namespace QtInterface {

/* 
 * This class represents an abstract viewport widget that can support any
 * graphics library as long as it can be integrated with Qt. This class utilizes
 * multiple inheritance due to the fact that it must also be a QWidget so that
 * it can be properly added to the interface; however the remainder of the
 * library-independent code resides within the Viewport class.
 */
class QViewport : public QWidget, public Viewport {
	Q_OBJECT

public:
	QViewport(QWidget* parent, const std::shared_ptr<GraphicsContext>& context, unsigned int fps = 60u, Qt::WFlags flags = 0);
	virtual ~QViewport();

	void update();
	void update(float dt);
	void updateAndRender();
	void resize(int width, int height);

	/* Viewport Interface Pass-through */
	virtual bool initialize() = 0;
	virtual void render() const = 0;
	virtual void reRender() const = 0;

	/* Qt Mouse Events */
	void mousePressEvent(QMouseEvent* e);
	void mouseReleaseEvent(QMouseEvent* e);
	void mouseMoveEvent(QMouseEvent* e);
	void wheelEvent(QWheelEvent* e);
	void enterEvent(QEvent* e);
	void leaveEvent(QEvent* e);
	void focusInEvent(QFocusEvent* e);
	void focusOutEvent(QFocusEvent* e);
	
	static bool TranslateMouseEvent(QMouseEvent* e, MouseButton& button, ModifierKey& modifierKey);

public slots:
	void onUpdateTimerTimeout();

protected:
	/* This is utilized to determine if the user has clicked a mouse button */
	Eigen::Vector2i mousePressPosition;

	/* 
	 * Update timer that can be used to update the viewport at a fixed
	 * interval.
	 */
	QTimer* updateTimer;
};

}

}

#endif
